package com.chao.wind3j.base.config.commonConfig.pageConfig;

import com.chao.wind3j.base.apiResult.ApiResult;
import com.chao.wind3j.model.base.pageVo.RPage;
import com.chao.wind3j.model.base.pageVo.WPage;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import java.util.List;

@Aspect
@Component
public class PageConfig implements Ordered {

  /**
   * 织入切面 - 分页 应用于有NeedPage注解以及最后一个参数为WPage类
   * @param joinPoint 切点
   * @return 添加了分页信息的对象
   * @throws Throwable 其中的异常，全抛出
   */
  @Around("needPage() && argsWPage()")
  public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
    return this.handlePage(joinPoint);
  }

  @Pointcut("@annotation(com.chao.wind3j.base.config.commonConfig.pageConfig.NeedCommonPage)")
  private void needPage() {
  }

  @Pointcut("args(*, com.chao.wind3j.model.base.pageVo.WPage)")
  private void argsWPage() {

  }

  public Object handlePage(ProceedingJoinPoint joinPoint) throws Throwable {
    var args = joinPoint.getArgs();
    WPage page = null;
    for (var item: args) {
      if (item instanceof WPage) {
        page = (WPage) item;
      }
    }
    var isStartPage = false;
    if (page != null && page.getPageIndex() != null && page.getPageSize() != null) {
      isStartPage = true;
      if (page.getOrder() != null) {
        PageHelper.startPage(page.getPageIndex(), page.getPageSize(), page.getOrder());
      } else {
        PageHelper.startPage(page.getPageIndex(), page.getPageSize());
      }
    }
    var result = (ApiResult<?>)joinPoint.proceed();
    // 返回的结果集里面是list才会判断是否要添加分页信息
    if (isStartPage && result.getResult() instanceof List) {
      var pageInfo = new PageInfo<>((List<?>)result.getResult());
      result.setPage(RPage.buildWithPageInfo(pageInfo));
    }
    return result;
  }

  @Override
  public int getOrder() {
    return 1;
  }
}
